// [[ OnflowGenerator File UUID: 3172baedc73a4d88a49b863b01080557  ]]
package com.itdct.onflow.system.task.service

import com.itdct.onflow.core.constant.CommonString
import com.itdct.onflow.core.constant.ReturnCode
import com.itdct.onflow.core.extend.*
import com.itdct.onflow.core.vo.KeyLabelValueVo
import com.itdct.onflow.core.vo.RespPageVo
import com.itdct.onflow.core.vo.RespVo
import com.itdct.onflow.system.common.base.BaseSysService
import com.itdct.onflow.system.common.context.Context
import com.itdct.onflow.system.common.extend.dict
import com.itdct.onflow.system.task.base.BaseTask
import com.itdct.onflow.system.task.constant.SysTaskExecuteStateConst
import com.itdct.onflow.system.task.entity.SysTaskEntity
import com.itdct.onflow.system.task.manager.SysTaskManager
import com.itdct.onflow.system.task.mapper.SysTaskMapper
import com.itdct.onflow.system.task.qo.SysTaskEditQo
import com.itdct.onflow.system.task.qo.SysTaskSearchQo
import com.itdct.onflow.system.task.vo.SysTaskDetailVo
import com.itdct.onflow.system.task.vo.SysTaskListVo
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author DCTANT
 * @date 2025-09-19 16:39:00
 * @version 1.0
 * @description 定时任务服务
 */
@Service
class SysTaskService(
    val sysTaskMapper: SysTaskMapper,
    val sysTaskManager: SysTaskManager,
    val redisTemplate: RedisTemplate<String, Any>
) : BaseSysService() {

    @Transactional(rollbackFor = [Exception::class])
    fun add(qo: SysTaskEditQo, context: Context): RespVo<Long> {
        val addEntity = qo.toEntity(SysTaskEntity::class.java)
        val id = sysTaskMapper.insertEx(addEntity)
        sysTaskManager.runTask(id)
        return success(id)
    }

    @Transactional(rollbackFor = [Exception::class])
    fun update(qo: SysTaskEditQo, context: Context): RespVo<Unit> {
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        val updateEntity = sysTaskMapper.selectByIdEx(id)
        qo.injectValue(updateEntity)
        sysTaskMapper.updateEx(updateEntity)
        sysTaskManager.stopTask(id)
        sysTaskManager.runTask(id)
        return success()
    }

    fun delete(qo: SysTaskEditQo, context: Context): RespVo<Unit> {
        val ids = qo.ids ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_DELETE_ID_LIST)
        val deleteEntities = sysTaskMapper.selectByIdsEx(ids)
        for (deleteEntity in deleteEntities) {
            sysTaskManager.stopTask(deleteEntity.id!!)
        }
        sysTaskMapper.deleteBatchEx(deleteEntities)
        return success()
    }

    fun detail(qo: SysTaskSearchQo, context: Context): RespVo<SysTaskDetailVo> {
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        val vo = sysTaskMapper.findById(id) ?: fail(CommonString.ENTITY_NOT_FOUND_USAGE("定时任务", id))
        return success(vo.dict())
    }

    fun page(qo: SysTaskSearchQo, context: Context): RespPageVo<SysTaskListVo> {
        startPage(context)
        val pageData = sysTaskMapper.findByList(qo)
        return successPage(pageData.dict())
    }

    fun runImmediately(qo: SysTaskEditQo, context: Context): RespVo<Unit> {
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        val sysTaskEntity = sysTaskMapper.selectByIdEx(id)
        val taskClass = sysTaskEntity.taskClass
        val taskObj: BaseTask?
        try {
            taskObj = Class.forName(taskClass).getDeclaredConstructor().newInstance() as BaseTask
        } catch (e: Exception) {
            fail("类无法找到")
        }
        val executeState = sysTaskEntity.executeState
        if (executeState == SysTaskExecuteStateConst.RUNNING) {
            fail("任务正在执行中")
        }
        val enable = sysTaskEntity.enable
        if (!enable) {
            fail("该任务没有启用")
        }

        sysTaskManager.beforeRun(id)
        taskObj.run(sysTaskEntity, redisTemplate)
        sysTaskManager.afterRun(id)

        return success()
    }

// [[ OnflowGenerator Range (- selectFunctions -) Start ]]

    fun selectNameList(qo: SysTaskSearchQo, context: Context): RespVo<List<KeyLabelValueVo>> {
        val vos = sysTaskMapper.selectNameList(qo)
        return success(vos)
    }
// [[ OnflowGenerator Range (- selectFunctions -) End ]]
}